package controller.editorcontroller;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTree;

import controller.commoncontroller.UtilityDialogs;

import view.UtilityConstants;
import view.editorview.ComponentPanel;

import model.LogicType;
import model.editormodel.EditorModel;
import model.editormodel.LogicEditorElement;
import model.editormodel.LogicSelfdefinedEditorElement;

/**
 * Listener der auf dem ComponentPanel liegt. Loest aus wenn man auf ein
 * selbstdefiniertes Bauteil rechtsklickt. Zeigt ein Popup an mit dem man das
 * ausgewaehlte selbstdefinierte Bauteil umbenennen kann.
 * 
 * @author Team Locsi
 * 
 */
public class ComponentPanelPopupListener extends MouseAdapter {

	/**
	 * Popup das angezeigt wird wenn der Listener ausloest.
	 */
	private JPopupMenu popup;

	/**
	 * Referenz auf den JTree der auf dem Panel liegt in dem sich die
	 * selbstdefinierten Bauteile befinden und dieser Listener liegt
	 */
	private JTree tree;

	/**
	 * Referenz auf das ComponentPanel auf dem die Elemente liegen
	 */
	private ComponentPanel cPanel;

	private Component parentForPositioning;

	/**
	 * Dieser Konstruktor erzeugt ein neues
	 * <code>ComponentPanelPopupListener</code>-Objekt
	 * 
	 * @param eModel
	 *            <code>EditorModel</code> - Referenz auf das EditorModel.
	 * @param tree
	 *            <code>JTree</code> - Referenz auf den JTree
	 * @param cPanel
	 *            <code>ComponentPanel</code> - Referenz auf das ComponentPanel
	 * @param parentForPositioning
	 *            <code>Component</code>
	 */
	public ComponentPanelPopupListener(EditorModel eModel, JTree tree,
			ComponentPanel cPanel, Component parentForPositioning) {
		this.parentForPositioning = parentForPositioning;
		this.tree = tree;
		this.cPanel = cPanel;
		this.popup = createPopup(eModel);
	}

	/**
	 * Diese Methode zeigt ein PopUp-Menue an, wenn ein selbstdefiniertes
	 * Bauteil mit Rechtsklick ausgewaehlt wird.
	 */
	@Override
	public void mouseClicked(MouseEvent e) {
		if (cPanel.getActualSelected() == LogicType.SELFDEFINED
				&& e.getButton() == MouseEvent.BUTTON3) {

			// wenn man rechtsklickt wird auch erstmal das unter dem klick
			// liegende selbstdefinierte bauteil ausgewaehlt
			tree.setSelectionPath(tree.getPathForLocation(e.getX(), e.getY()));
			popup.show(tree, e.getX(), e.getY());
		}
	}

	/**
	 * Diese private Methode erzeugt ein Popup-Menu mit den Items "Umbennen" und
	 * "Loeschen"
	 */
	private JPopupMenu createPopup(final EditorModel eModel) {
		JPopupMenu popUp = new JPopupMenu();
		JMenuItem[] items = new JMenuItem[2];
		items[0] = new JMenuItem("Umbenennen");
		items[1] = new JMenuItem("Löschen");

		// ActionListener werden auf die Items gelegt
		items[0].addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				String newName = JOptionPane.showInputDialog(
						parentForPositioning, "Neuer Name des Bauteils: ",
						cPanel.getNameOfSelectedSelfDefined());
				if (newName != null
						&& !newName.equals(cPanel
								.getNameOfSelectedSelfDefined())) {
					if (!eModel.getParser().renameSelfdefined(
							cPanel.getNameOfSelectedSelfDefined(), newName)) {
						JOptionPane.showMessageDialog(cPanel.getParent(),
								"Umbenennen fehlgeschlagen!", null,
								JOptionPane.ERROR_MESSAGE);
					} else {
						eModel.getComponentHandler().refreshComponentList();
						if (JOptionPane
								.showConfirmDialog(
										parentForPositioning,
										"<html><body>Sollen im Schaltplan schon vorhandene<br> Bauteile dieses Typs umbenannt werden?</body></html>",
										null, JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {

							List<LogicEditorElement> toRename = new ArrayList<LogicEditorElement>();
							for (LogicEditorElement lEE : eModel
									.getCircuitModel()
									.getUnmodifableElementsOnEditor().values()) {

								if (lEE.getType() == LogicType.SELFDEFINED) {
									if (cPanel
											.getNameOfSelectedSelfDefined()
											.equals(((LogicSelfdefinedEditorElement) lEE)
													.getcModel().getName())) {
										toRename.add(lEE);
									}
								}
							}

							for (LogicEditorElement lEE : toRename) {
								eModel.renameElement(
										lEE.getName(),
										newName
												+ "_"
												+ lEE.getName().split("_")[lEE
														.getName().split("_").length - 1]);
							}
						}
					}
				}
			}
		});

		items[1].addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				File xmlFile = new File(UtilityConstants.SD_DIRECTORY
						+ cPanel.getNameOfSelectedSelfDefined()
						+ UtilityDialogs.XML_EXTENSION);
				File picFile = new File(UtilityConstants.SD_DIRECTORY
						+ cPanel.getNameOfSelectedSelfDefined()
						+ UtilityDialogs.PNG_EXTENSION);
				if (xmlFile.exists()) {
					xmlFile.delete();

					// Wenn der Benutzer aus der Bauteilauswahlliste ein SD-B
					// löscht, kann er entscheiden ob er die schon in der
					// Schaltung verbauten Bauteile dieses Typs auch gelöscht
					// werden sollen falls NEIN wird der zugehörige screenshot
					// auch erst bei beenden des Programms gelöscht
					if (JOptionPane
							.showConfirmDialog(
									parentForPositioning,
									"<html><body>Sollen im Schaltplan schon vorhandene<br> Bauteile dieses Typs entfernt werden?</body></html>",
									null, JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
						List<String> toDelete = new ArrayList<String>();
						for (LogicEditorElement lEE : eModel.getCircuitModel()
								.getUnmodifableElementsOnEditor().values()) {

							if (lEE.getType() == LogicType.SELFDEFINED) {
								if (cPanel
										.getNameOfSelectedSelfDefined()
										.equals(((LogicSelfdefinedEditorElement) lEE)
												.getcModel().getName())) {
									toDelete.add(lEE.getName());
								}
							}
						}
						eModel.deleteLogicElements(toDelete);
						if (picFile.exists()) {
							picFile.delete();
						}
					} else {
						if (picFile.exists()) {
							picFile.deleteOnExit();
						}
					}
				}

				eModel.getComponentHandler().refreshComponentList();
			}
		});
		popUp.add(items[0]);
		popUp.add(items[1]);
		return popUp;
	}
}
